package com.qf.config;

import com.qf.filter.JwtVerifyFilter;
import com.qf.filter.LoginFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

//    public static void main(String[] args) {
//        String hashpw = BCrypt.hashpw("1234", BCrypt.gensalt());
//        System.out.println(hashpw);
//    }


    //设置security的密码加密器
    @Bean
    public PasswordEncoder passwordEncoder(){
        //不加密的密码编码器
//        return NoOpPasswordEncoder.getInstance();
        //返回一个Bcrypt密码加密器
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭跨站伪造攻击
        http.csrf().disable();
        //关闭帧标签的限制头
        http.headers().frameOptions().disable();
        //设置跨域访问
        http.cors().configurationSource(cs());

        //添加过滤器(/login资源就可以的到处理)
        http.addFilter(new LoginFilter(authenticationManager()))
                .addFilter(new JwtVerifyFilter(authenticationManager()));


        //配置哪些资源需要登录、哪些资源需要什么权限
        http.authorizeRequests()
                //要求，/user下的所有资源必须登录
                .antMatchers("/user/**").authenticated()
                //要求，/user下的所有资源必须有P1角色权限
//                .antMatchers("/user/**").hasRole("P1")
//                .antMatchers("/order/**").authenticated()
//                .antMatchers("/setmeal/**").authenticated()

                //除了上述配置的资源外，其他的都直接放行
                .antMatchers("/**").permitAll();

        //关闭session保存
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    /**
     * 设置跨域访问的配置元信息
     * @return
     */
    private CorsConfigurationSource cs() {
        UrlBasedCorsConfigurationSource ccs = new UrlBasedCorsConfigurationSource();
        CorsConfiguration cc = new CorsConfiguration();
        //允许哪些域进行跨域访问.*表示所有域都允许
        cc.setAllowedOrigins(Arrays.asList("*"));
        //允许哪些请求方式跨域访问，*表示任意请求方式
        cc.setAllowedMethods(Arrays.asList("*"));
        //允许跨域访问时，携带哪些头。*表示任意头
        cc.setAllowedHeaders(Arrays.asList("*"));

        //允许跨域访问时，响应携带的头信息。*表示任意头
        cc.setExposedHeaders(Arrays.asList("*"));

        ccs.registerCorsConfiguration("/**",cc);

        return ccs;
    }
}
